package com.ruoyi.merchant.service.impl;

import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.merchant.domain.Announcement;
import com.ruoyi.merchant.domain.dto.AnnouncementAddDTO;
import com.ruoyi.merchant.domain.dto.AnnouncementQueryDTO;
import com.ruoyi.merchant.domain.dto.AnnouncementUpdateDTO;
import com.ruoyi.merchant.domain.vo.AnnouncementDetailVO;
import com.ruoyi.merchant.domain.vo.AnnouncementListVO;
import com.ruoyi.merchant.enums.AnnouncementStatusEnum;
import com.ruoyi.merchant.mapper.AnnouncementMapper;
import com.ruoyi.merchant.service.IAnnouncementService;
import com.ruoyi.merchant.utils.MerchantSecurityUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

/**
 * 商家端公告Service业务层处理
 */
@Service
public class AnnouncementServiceImpl implements IAnnouncementService {
    
    @Autowired
    private AnnouncementMapper announcementMapper;
    
    /**
     * 新增公告
     *
     * @param addDTO 公告信息
     * @return 公告ID
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long addAnnouncement(AnnouncementAddDTO addDTO) {
        // 获取商家ID
        Long merchantId = MerchantSecurityUtils.getMerchantId();
        if (merchantId == null) {
            throw new ServiceException("未登录或登录已过期");
        }
        
        // 校验状态
        if (!AnnouncementStatusEnum.DRAFT.getCode().equals(addDTO.getStatus()) 
            && !AnnouncementStatusEnum.PUBLISHED.getCode().equals(addDTO.getStatus())) {
            throw new ServiceException("公告状态只能是草稿或发布");
        }
        
        // 如果是发布状态，必须有发布时间
        if (AnnouncementStatusEnum.PUBLISHED.getCode().equals(addDTO.getStatus())) {
            if (addDTO.getPublishTime() == null) {
                addDTO.setPublishTime(new Date());
            }
        }
        
        // 创建公告实体
        Announcement announcement = new Announcement();
        BeanUtils.copyProperties(addDTO, announcement);
        announcement.setMerchantId(merchantId);
        announcement.setScope(3); // 商户公告
        
        // 插入公告
        int rows = announcementMapper.insertAnnouncement(announcement);
        if (rows == 0) {
            throw new ServiceException("新增公告失败");
        }
        
        return announcement.getAnnouncementId();
    }
    
    /**
     * 查询历史公告列表
     *
     * @param query 查询条件
     * @return 公告列表
     */
    @Override
    public List<AnnouncementListVO> getAnnouncementList(AnnouncementQueryDTO query) {
        // 获取商家ID
        Long merchantId = MerchantSecurityUtils.getMerchantId();
        if (merchantId == null) {
            throw new ServiceException("未登录或登录已过期");
        }
        
        // 设置商家ID到查询条件
        query.setMerchantId(merchantId);
        
        // 查询公告列表
        return announcementMapper.selectMerchantAnnouncementList(query);
    }
    
    /**
     * 查询公告详情
     *
     * @param announcementId 公告ID
     * @return 公告详情
     */
    @Override
    public AnnouncementDetailVO getAnnouncementDetail(Long announcementId) {
        // 获取商家ID
        Long merchantId = MerchantSecurityUtils.getMerchantId();
        if (merchantId == null) {
            throw new ServiceException("未登录或登录已过期");
        }
        
        // 查询公告详情
        Announcement announcement = announcementMapper.selectAnnouncementById(
            announcementId, merchantId
        );
        if (announcement == null) {
            throw new ServiceException("公告不存在或无权查看");
        }
        
        // 转换为VO
        AnnouncementDetailVO vo = new AnnouncementDetailVO();
        BeanUtils.copyProperties(announcement, vo);
        vo.setStatusName(AnnouncementStatusEnum.getDescByCode(announcement.getStatus()));
        
        return vo;
    }

    /**
     * 更新公告
     *
     * @param announcementId 公告ID
     * @param updateDTO 更新信息
     * @return 是否成功
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateAnnouncement(Long announcementId, AnnouncementUpdateDTO updateDTO) {
        // 获取商家ID
        Long merchantId = MerchantSecurityUtils.getMerchantId();
        if (merchantId == null) {
            throw new ServiceException("未登录或登录已过期");
        }

        // 查询公告是否存在
        Announcement announcement = announcementMapper.selectAnnouncementById(
                announcementId, merchantId
        );
        if (announcement == null) {
            throw new ServiceException("公告不存在或无权修改");
        }

        // 只能修改草稿状态的公告
        if (!AnnouncementStatusEnum.DRAFT.getCode().equals(announcement.getStatus())) {
            throw new ServiceException("只能修改草稿状态的公告");
        }

        // 更新公告
        Announcement updateEntity = new Announcement();
        updateEntity.setAnnouncementId(announcementId);
        updateEntity.setMerchantId(merchantId);
        BeanUtils.copyProperties(updateDTO, updateEntity);

        int rows = announcementMapper.updateAnnouncement(updateEntity);
        return rows > 0;
    }

    /**
     * 发布公告（草稿转发布）
     *
     * @param announcementId 公告ID
     * @return 是否成功
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean publishAnnouncement(Long announcementId) {
        // 获取商家ID
        Long merchantId = MerchantSecurityUtils.getMerchantId();
        if (merchantId == null) {
            throw new ServiceException("未登录或登录已过期");
        }

        // 查询公告是否存在
        Announcement announcement = announcementMapper.selectAnnouncementById(
                announcementId, merchantId
        );
        if (announcement == null) {
            throw new ServiceException("公告不存在或无权操作");
        }

        // 只能发布草稿状态的公告
        if (!AnnouncementStatusEnum.DRAFT.getCode().equals(announcement.getStatus())) {
            throw new ServiceException("只有草稿状态的公告才能发布");
        }

        // 更新状态为已发布
        int rows = announcementMapper.updateAnnouncementStatus(
                announcementId,
                merchantId,
                AnnouncementStatusEnum.PUBLISHED.getCode(),
                new Date()  // 发布时间设为当前时间
        );

        return rows > 0;
    }

    /**
     * 下线公告
     *
     * @param announcementId 公告ID
     * @return 是否成功
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean offlineAnnouncement(Long announcementId) {
        // 获取商家ID
        Long merchantId = MerchantSecurityUtils.getMerchantId();
        if (merchantId == null) {
            throw new ServiceException("未登录或登录已过期");
        }

        // 查询公告是否存在
        Announcement announcement = announcementMapper.selectAnnouncementById(
                announcementId, merchantId
        );
        if (announcement == null) {
            throw new ServiceException("公告不存在或无权操作");
        }

        // 只能下线已发布的公告
        if (!AnnouncementStatusEnum.PUBLISHED.getCode().equals(announcement.getStatus())) {
            throw new ServiceException("只有已发布的公告才能下线");
        }

        // 更新状态为已下线
        int rows = announcementMapper.updateAnnouncementStatus(
                announcementId,
                merchantId,
                AnnouncementStatusEnum.OFFLINE.getCode(),
                null
        );

        return rows > 0;
    }
    
    /**
     * 删除公告
     *
     * @param announcementId 公告ID
     * @return 是否成功
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteAnnouncement(Long announcementId) {
        // 获取商家ID
        Long merchantId = MerchantSecurityUtils.getMerchantId();
        if (merchantId == null) {
            throw new ServiceException("未登录或登录已过期");
        }
        
        // 软删除公告
        int rows = announcementMapper.deleteAnnouncementById(announcementId, merchantId);
        if (rows == 0) {
            throw new ServiceException("公告不存在或无权删除");
        }
        
        return true;
    }
}
